// EAN13.js - EAN-13 条码实现（13位数字）
// 支持12位输入自动补校验码，首位决定左侧编码结构（L/G）
// 参考：https://en.wikipedia.org/wiki/International_Article_Number_(EAN)

import EAN from './EAN.js';
import { EAN13_STRUCTURE } from './constants.js';

/**
 * 计算 EAN-13 条码的校验码
 * 规则：从左到右，第1位为奇数位（×1），第2位为偶数位（×3）
 * 校验码 = (10 - (加权和 % 10)) % 10
 *
 * @param {string|number} number - 前12位数字（字符串或数字）
 * @returns {number} 校验码（0-9）
 *
 * @example
 * checksum('490123456789') // → 0
 * checksum(490123456789)   // → 0
 */
function checksum(number) {
	// 转为字符串并提取前12位
	const numStr = String(number).trim().substr(0, 12);

	// 验证是否全为数字
	if (!/^\d{12}$/.test(numStr)) {
		throw new Error('输入必须为12位数字');
	}

	const sum = numStr
		.split('')
		.map(char => parseInt(char, 10))
		.reduce((total, digit, index) => {
			// index 从 0 开始：第1位（index=0）是奇数位 → ×1；第2位（index=1）是偶数位 → ×3
			return index % 2 === 0 ? total + digit : total + digit * 3;
		}, 0);

	return (10 - (sum % 10)) % 10;
}

export class EAN13 extends EAN {
	/**
	 * 构造函数
	 * @param {string} data - 12 或 13 位数字
	 * @param {Object} options - 配置项，支持 lastChar（末尾字符）
	 */
	constructor(data, options) {
		// 如果是12位数字，自动补上校验码
		if (/^[0-9]{12}$/.test(data)) {
			data += checksum(data);
		}

		super(data, options);

		// 保存附加字符（如价格码）
		this.lastChar = options.lastChar || null;
	}

	/**
	 * 验证 EAN-13 是否有效
	 * 1. 必须是13位数字
	 * 2. 最后一位必须等于 checksum(前12位)
	 * @returns {boolean}
	 */
	valid() {
		return (
			/^[0-9]{13}$/.test(this.data) &&
			parseInt(this.data[12], 10) === checksum(this.data)
		);
	}

	/**
	 * 获取左侧文本（第2-7位）
	 * @returns {string}
	 */
	leftText() {
		return super.leftText(1, 6);
	}

	/**
	 * 编码左侧6位（第2-7位），编码方式由第1位决定（L/G 结构）
	 * @returns {string} 二进制条码
	 */
	leftEncode() {
		const data = this.data.substr(1, 6);
		const structure = EAN13_STRUCTURE[this.data[0]];
		return super.leftEncode(data, structure);
	}

	/**
	 * 获取右侧文本（第8-13位）
	 * @returns {string}
	 */
	rightText() {
		return super.rightText(7, 6);
	}

	/**
	 * 编码右侧6位（第8-13位），使用 R 编码表
	 * @returns {string} 二进制条码
	 */
	rightEncode() {
		const data = this.data.substr(7, 6);
		return super.rightEncode(data, 'RRRRRR');
	}

	/**
	 * 生成带守卫条的完整编码（用于图形渲染）
	 * 并在左侧显示第一位数字，右侧可附加字符
	 * @returns {Array<{ data: string, text?: string, options?: Object }>}
	 */
	encodeGuarded() {
		let data = super.encodeGuarded();

		if (this.options.displayValue) {
			// 添加第一位数字（左侧扩展）
			data.unshift({
				data: '000000000000', // 占位宽度（11个0，实际不打印条码）
				text: this.data[0],
				options: {
					textAlign: 'left',
					fontSize: this.fontSize,
				},
			});

			// 添加附加字符（如价格码）
			if (this.lastChar) {
				data.push({ data: '00' }); // 小间隔
				data.push({
					data: '00000', // 占位
					text: this.lastChar,
					options: {
						fontSize: this.fontSize,
					},
				});
			}
		}

		return data;
	}
}

